#include "ComServer.h"
#include <stdio.h>
#include "winsock.h"
#include <iostream>

using namespace std;

ComServer::ComServer() {

}
// ----------
// Destruktor, provadu uklid po winsock
ComServer::~ComServer() {
  WSACleanup();
}
// ----------
// Nastavi server aby naslouchal na zadane ip adrese a portu
// Ceka na pripojeji klientu
int ComServer::Listen(string ip, int port) {
  //----------------------
  // Inicializace WinSock
  WSADATA wsaData;
  int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
  if (iResult != NO_ERROR) {
	  printf("Error: Inicializace WinSock se nezdarila\n");
	  return 1;
  }

  //----------------------
  // Vytvari SOCKET, na kterem bude server naslouchat 
  SOCKET ListenSocket;
  ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (ListenSocket == INVALID_SOCKET) {
    printf("Error: Chyba pri vytvareni socketu (%ld)\n", WSAGetLastError());
    WSACleanup();
    return 1;
  }

  //----------------------
  // Prirazeni ip adresy a portu serveru
  sockaddr_in service;
  service.sin_family = AF_INET;
  service.sin_addr.s_addr = inet_addr(ip.c_str());
  service.sin_port = htons(port);

  if (bind( ListenSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR) {
	  printf("Error: Prikaz bind() selhal.\n");
	  closesocket(ListenSocket);
      return 1;
  }

  //----------------------
  // Server zacina naslouchat na zadanem portu
  if (listen( ListenSocket, 1 ) == SOCKET_ERROR) {
	  printf("Error: Prikaz listen selhal.\n");
	  return 1;
  }

  printf("Server ceka na pripojeni klietu ...\n");

  //----------------------
  // Pripojeni klientu
  this->clients[0] = SOCKET_ERROR;
  while( this->clients[0] == SOCKET_ERROR ) {
    this->clients[0] = accept( ListenSocket, NULL, NULL );
  }
  printf("Klient[0] se pripojil.\n");

  this->clients[1] = SOCKET_ERROR;
  while( this->clients[1] == SOCKET_ERROR ) {
    this->clients[1] = accept( ListenSocket, NULL, NULL );
  }
  printf("Klient[1] se pripojil.\n");

  return 0;
}


// ----------
// Ceka na zpravu od zadaneho klienta a prijme ji
int ComServer::RecieveData(ComData* data, int client) {
	char buf[1024*16];
	int size = -1;
  
	int bytesRecv = recv(this->clients[client], buf, 1024*16, 0);
  string xmlData = buf;
	
	data->FromXML(xmlData);
	//int bytesRecv = recv( this->clients[client], (char*)data, sizeof(ComData), 0 );

	return bytesRecv;
}
// ----------
// Odesle data zadanemu klientovi
int ComServer::SendData(ComData data, int client) {
	std::string xmlData = data.ToXML();
	int bytesSent = send( this->clients[client], xmlData.c_str(), xmlData.size() +1, 0 );

	//int bytesSent = send( this->clients[client], (char *)&data, sizeof(ComData), 0 );
	return bytesSent;
}